package plugins.repertoireDetail;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import annotation.Menu;

import interfaces.PluginInterface;
import interfaces.RepertoireInterface;

public class RepertoireDetail implements RepertoireInterface {
	
	private JPanel 					repertoire,pRetour, centre,detail;
	private JLabel 					labelRetour,labelActuel,labelVide;
	private JButton 				retour;
	private File 					parent=null;
	private List<PluginInterface> 	liste;
	private int 					i;
	private Dimension 				d 					= new Dimension(200,120);
	private boolean 				parDefaut 			= false;
	private List<String> 			listeOpenedFiles   	= new ArrayList<String>();
	private File 					savingFile         	= new File("openedFile.mem");
	private StringBuilder           texteDetail= new StringBuilder("");
	private DateFormat              dateFormat;
	

	public RepertoireDetail(){
		
		dateFormat = DateFormat.getDateInstance(DateFormat.SHORT, Locale.getDefault());
		repertoire  = new JPanel();
		detail = new JPanel();
		labelRetour = new JLabel("Poste de travail");
		labelActuel = new JLabel("Poste de travail");
		labelVide   = new JLabel("Dossier Vide !");
		
		labelRetour.setPreferredSize(new Dimension(100, 20));
		labelRetour.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
		
		labelActuel.setPreferredSize(new Dimension(200, 20));
		labelActuel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
		
		repertoire.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
		repertoire.setPreferredSize(new Dimension(500,1900));
		
		pRetour = new JPanel();
		pRetour.setLayout(new GridLayout(0,3,10,90));
		pRetour.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
		
		retour = new JButton("<= Retour");
		retour.setBackground(Color.BLACK);
		retour.setForeground(Color.WHITE);
		retour.setPreferredSize(new Dimension(100, 20));
		retour.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				build(parent.getParentFile(), liste);	
				parent=parent.getParentFile();
			}
		});
		
		pRetour.add(labelRetour, BorderLayout.WEST);
		pRetour.add(retour,BorderLayout.CENTER);
		pRetour.add(labelActuel, BorderLayout.EAST);
		
		centre = new JPanel();
		centre.setLayout(new BorderLayout());
		centre.add(pRetour, BorderLayout.NORTH);
		centre.add(repertoire,BorderLayout.CENTER);
		centre.add(detail, BorderLayout.EAST);
		
		
	}
	public JPanel build(File f, final List<PluginInterface> l)
	{
		
		repertoire.removeAll();
		liste=l;
		if(f==null || f.getName().equals("Poste de travail"))
		{
			File[] drive;
            drive = File.listRoots();
            for (int i = 0; i < drive.length; i++) {
            	final File root = drive[i];
            	JButton b = new JButton(drive[i].getPath());
            	b.setPreferredSize(d);
            	b.addActionListener(new ActionListener() {
					
					@Override
					public void actionPerformed(ActionEvent arg0) {
						build(root, l);
					}
				});
            	repertoire.add(b);
            }
			labelRetour.setVisible(false);
			retour.setEnabled(false);
			labelActuel.setText("     Courant :    Poste de travail");
		}
		else
		{
			retour.setEnabled(true);
			labelRetour.setVisible(true);
			labelActuel.setText("     Courant :    "+f.getPath());
			if(f.getParentFile() == null)
				labelRetour.setText("     Poste de travail");
			else
				labelRetour.setText(f.getParentFile().getPath());
			
			
			if(f.isDirectory())
			{
				parent = f;
				File[] temp = f.listFiles();// contient tous les sous dossier (fichiers)
				if(temp == null)
					pRetour.add(labelVide);
				else
				if(temp.length==0){
					pRetour.add(labelVide);
				}
				else
				{
					pRetour.remove(labelVide);
					JLabel[] b = new JLabel[temp.length];
					for (i=0 ; i<f.listFiles().length ; i++) {
						final File file = temp[i];
						
						if(file.isDirectory())
						{
							texteDetail.delete(0, texteDetail.length());
							texteDetail.append("<HTML>");
							texteDetail.append("nom : "+file.getName());
							texteDetail.append("<br>");
							if(file.listFiles() !=null)
								texteDetail.append("files : "+file.list().length);
							else
								texteDetail.append("files : 0");
							texteDetail.append("<br>");
							texteDetail.append("modifié : "+dateFormat.format(new Date(file.lastModified())));
							
							b[i] = new JLabel(texteDetail.toString(),new ImageIcon("../Plugin/bin/plugins/repertoireDetail/folder.png"),0);
							b[i].setOpaque(true);
							b[i].setVerticalAlignment(JLabel.BOTTOM);
						    b[i].setHorizontalTextPosition(JLabel.RIGHT);
						    //b[i].setVerticalTextPosition(JLabel.BOTTOM);
							b[i].setPreferredSize(d);
							repertoire.add(b[i]);
							b[i].addMouseListener(new MouseListener() {
								
								@Override
								public void mouseReleased(MouseEvent e) {
									// TODO Auto-generated method stub
									
								}
								
								@Override
								public void mousePressed(MouseEvent e) {
									// TODO Auto-generated method stub
									
								}
								
								@Override
								public void mouseExited(MouseEvent e) {
									// TODO Auto-generated method stub
									
								}
								
								@Override
								public void mouseEntered(MouseEvent e) {
									// TODO Auto-generated method stub
									
								}
								
								@Override
								public void mouseClicked(MouseEvent e) {
									repertoire.removeAll();
									build(file, l);
									repertoire.setVisible(false);
									repertoire.validate();
									repertoire.setVisible(true);
									
								}
							});
						}
						else
						{
							texteDetail.delete(0, texteDetail.length());
							texteDetail.append("<HTML>");
							texteDetail.append("nom : "+file.getName());
							texteDetail.append("<br>");
							texteDetail.append("Taille : "+file.getUsableSpace()/1000);
							texteDetail.append("<br>");
							texteDetail.append("modifié : "+dateFormat.format(new Date(file.lastModified())));
							
							if(getRightPlugin(getFileExtension(file), l) != null)
								b[i] = new JLabel(texteDetail.toString(),getRightPlugin(getFileExtension(file), l).getIcon(),JLabel.CENTER);
							else
								b[i] = new JLabel(texteDetail.toString(),new ImageIcon("../Plugin/bin/plugins/repertoireDetail/noIcon.png"),JLabel.CENTER);
							
							b[i].setVerticalAlignment(JLabel.BOTTOM);
						    b[i].setHorizontalTextPosition(JLabel.RIGHT);
						    //b[i].setVerticalTextPosition(JLabel.BOTTOM);
							b[i].setPreferredSize(d);
							b[i].setOpaque(true);
							repertoire.add(b[i]);
							b[i].addMouseListener(new MouseListener() {
								
								@Override
								public void mouseReleased(MouseEvent e) {
									// TODO Auto-generated method stub
									
								}
								
								@Override
								public void mousePressed(MouseEvent e) {
									// TODO Auto-generated method stub
									
								}
								
								@Override
								public void mouseExited(MouseEvent e) {
									// TODO Auto-generated method stub
									
								}
								
								@Override
								public void mouseEntered(MouseEvent e) {
									// TODO Auto-generated method stub
									
								}
								
								@Override
								public void mouseClicked(MouseEvent e) {
									runFile(file, l);
								}
							});
						}
					}
				}
			}
		}
		repertoire.setVisible(false);
		repertoire.validate();
		repertoire.setVisible(true);
		return centre;
	}
	
	
	@Override
	public JPanel getFrameDetail() {
		JPanel p = new JPanel();
		p.setLayout(new GridLayout(10, 3));
		p.add(new JLabel("Details      : repertoire détaillé"));
		p.add(new JLabel("Version     : "+getVersion()));
		StringBuilder extension = new StringBuilder("");
		for(String e : getExtension())
			extension.append(" | "+e);
		p.add(new JLabel("Extension : "+extension));
		if(isDefault())
			p.add(new JLabel("par défaut  : Oui"));
		
		return p;
	}

	@Override
	public String[] getExtension() {
		return new String[]{"dossier"};
	}

	@Override
	public String getVersion() {
		return "0.1";
	}

	@Override
	public boolean isDefault() {
		return parDefaut;
	}

	@Override
	public void setDefault(boolean bool) {
		parDefaut = bool;

	}
	@Menu(libelle="repertoiredetail")
	@Override
	public JPanel getFrame(File f, List<PluginInterface> l) {
		return build(f, l);
	}

	@Override
	public void runFile(final File f, List<PluginInterface> l) {
		if(f.isFile())
		{
			if(l != null)
			{
				if(getRightPlugin(getFileExtension(f), l) != null )
				{
					getRightPlugin(getFileExtension(f), l).getFrame(f).addWindowListener(new WindowAdapter(){
						  public void windowClosing(WindowEvent we){
							  listeOpenedFiles.remove(listeOpenedFiles.indexOf(f.getAbsolutePath()));
						  }
					});
					listeOpenedFiles.add(f.getAbsolutePath());
				}
				else
					JOptionPane.showMessageDialog(null, "Cette extension : \""+getFileExtension(f)+"\" n'est pas prise en charge");
			}
			else
				JOptionPane.showMessageDialog(null, "Cette extension : \""+getFileExtension(f)+"\" n'est pas prise en charge");
		}

	}

	@Override
	public File getlastOpenedDir() {
		return parent;
	}

	@Override
	public void saveOpenedFiles() {
		try {
			
			FileOutputStream   fosf = new FileOutputStream(savingFile.getAbsolutePath());
			ObjectOutputStream oosf = new ObjectOutputStream(fosf);
			try {
				oosf.writeObject(listeOpenedFiles); 
				oosf.flush();
			} finally {
				try {
					oosf.close();
				} finally {
					fosf.close();
				}
			}
		} catch(IOException ioe) {
			ioe.printStackTrace();
		}
	}

	@Override
	public void loadOpenedFile() {
		if(savingFile.exists())
		{
			try {
				FileInputStream fisf   = new FileInputStream(savingFile.getAbsolutePath());
				ObjectInputStream oisf = new ObjectInputStream(fisf);
				try {	
					// désérialisation : lecture de l'objet depuis le flux d'entrée
					 @SuppressWarnings("unchecked")
					List<String> newListeOpenedFiles   = (List<String>) oisf.readObject(); 
					 for(String path : newListeOpenedFiles)
					 {
						 runFile(new File(path), liste);
					 }
					
				} finally {
					try {
						oisf.close();
					} finally {
						fisf.close();
					}
				}
			} catch(IOException ioe) {
				ioe.printStackTrace();
			} catch(ClassNotFoundException cnfe) {
				cnfe.printStackTrace();
			}
		}
	}

	@Override
	public String getTypeAffichage() {
		// TODO Auto-generated method stub
		return "Détail";
	}
	
	/**
	 * Calcule l'extension d'un fichier et la renvoie
	 * @param f File
	 * @return extension String
	 */
	public static String getFileExtension(File f)
	{
		int index = f.getName().lastIndexOf(".");
		
		return f.getName().substring(index+1, f.getName().length());
	}
	
	/**
	 * Cette fonction renvoi le plugin prenant en compte un fichier dont en passe son extension en parametre
	 * @param extension String
	 * @param l 		List<PluginInterface>
	 * @return PluginInterface or null
	 */
	public static PluginInterface getRightPlugin(String extension , List<PluginInterface> l)
	{
		for(PluginInterface p : l)
		{
			String[] ext = p.getExtension();
			for(String e : ext)
			if(extension.equals(e))
				return p;
		}
		return null;
	}

}
